package com.swak.entity;

import java.io.Serializable;

import com.swak.utils.StringUtils;

public abstract class ParentDTO<T> implements Serializable {

	private static final long serialVersionUID = 1L;

	public abstract Long getId();

	public abstract T setId(Long id);

	public abstract String getName();

	public abstract T setName(String name);

	public abstract Long getParentId();

	public abstract T setParentId(Long parentId);

	public abstract String getParentName();

	public abstract T setParentName(String name);

	public abstract String getParentIds();

	public abstract T setParentIds(String parentIds);

	public abstract String getPath();

	public abstract T setPath(String path);

	public abstract Byte getLevel();

	public abstract T setLevel(Byte level);

	/**
	 * 保存返回子类对象
	 * 
	 * @param <T>
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public T as() {
		return (T) this;
	}

	/**
	 * 将父区域中的属性添加到子区域中
	 * 
	 * @param parent
	 */
	public T fillByParent(ParentDTO<T> parent) {
		Long parentId = parent == null ? -1 : parent.getId();
		String parentName = parent == null ? StringUtils.EMPTY : parent.getName();
		int level = parent == null ? 0 : parent.getLevel();
		String parentIds = parent == null ? StringUtils.EMPTY
				: (new StringBuilder(StringUtils.defaultIfBlank(parent.getParentIds(), StringUtils.EMPTY))
						.append(parent.getId()).append(",").toString());
		this.setParentId(parentId);
		this.setParentName(parentName);
		this.setLevel((byte) (level + 1));
		this.setParentIds(parentIds);
		this.setPath(StringUtils.abbreviate(new StringBuilder(
				(parent == null ? StringUtils.EMPTY : StringUtils.defaultString(parent.getPath(), StringUtils.EMPTY)))
				.append("/").append(this.getName()).toString(), 255));
		return as();
	}

	/**
	 * 替换属性
	 * 
	 * @param parent
	 * @param oldParentIds
	 * @param oldPaths
	 * @param oldLevel
	 * @return
	 */
	public T fillByParent(ParentDTO<T> parent, String oldParentIds, String oldPaths, Byte oldLevel) {
		String parentIds = this.getParentIds().replace(oldParentIds, parent.getParentIds());
		this.setParentIds(parentIds);
		int changeLevel = parent.getLevel() - oldLevel;
		this.setLevel((byte) (this.getLevel() + changeLevel));
		String paths = this.getPath().replace(oldPaths + "/", parent.getPath() + "/");
		this.setPath(paths);
		return as();
	}

	/**
	 * 修改Path
	 * 
	 * @param parent
	 * @param oldPaths
	 * @return
	 */
	public T fillByParent(ParentDTO<T> parent, String oldPaths) {
		String paths = this.getPath().replace(oldPaths + "/", parent.getPath() + "/");
		this.setPath(paths);
		return as();
	}
}
